class SSCardLogic {
	/** 牌型名字 */
	public static typeName:string[] = ["","乌龙","对子","两对","三张","顺子","顺子","顺子","同花","葫芦","铁支","同花顺","同花顺"];
	/** 服务器牌型对应资源名 */
	public static serverTypeSource:string[] = ["ssGame.type0","ssGame.type0","ssGame.type1","ssGame.type3","ssGame.type2","ssGame.type4","ssGame.type4","ssGame.type4","ssGame.type5","ssGame.type6","ssGame.type7","ssGame.type8","ssGame.type8"];
	/** 最大13张 */
	public static maxcount = 5;
	/** 花色掩码 */
	public static maskColor = 0xF0;
	/** 数值掩码 */
	public static maskValue = 0x0F;

	/** 客户端的牌型 */
	public static type =
	{
		/** 对子*/ T1: 1,
		/** 两对*/ T2: 2, 
		/** 三张*/ T3: 3,
		/** 顺子*/ T4: 4,
		/** 同花*/ T5: 5,
		/** 葫芦*/ T6: 6,
		/** 铁支*/ T7: 7,
		/** 同花顺*/ T8: 8,
	};

	/** 检测是否有哪些牌型 */
	public static getTypes(cards: number[]):number[]{
		let ts = [], ov = 0, vl = 0;
		let vn = SSCardLogic.valueNum(cards), cn = SSCardLogic.colorNum(cards);
		for(let k in vn){
			let v = parseInt(k);
			if(v - ov == 1) vl++;
			else vl = 1;
			if(vn[k] == 4){
				if(SSCardLogic.type.T1 in ts) ts[SSCardLogic.type.T6] = 1;
				ts[SSCardLogic.type.T7] = 1;
				ts[SSCardLogic.type.T3] = 1;
				ts[SSCardLogic.type.T1] = 1;
			}else if(vn[k] == 3){
				if(SSCardLogic.type.T1 in ts) ts[SSCardLogic.type.T6] = 1;
				ts[SSCardLogic.type.T3] = 1;
				ts[SSCardLogic.type.T1] = 1;
			}else if(vn[k] == 2){
				if(SSCardLogic.type.T3 in ts) ts[SSCardLogic.type.T6] = 1;
				ts[SSCardLogic.type.T1] = 1;
			}
			if(vl > 4) ts[SSCardLogic.type.T4] = 1;
			ov = v
		}
		for(let k in cn){
			if(cn[k] > 4){
				ts[SSCardLogic.type.T5] = 1;
				vl = 0;
				for(let i=1;i<14;i++){
					if(i in vn && cards.indexOf(parseInt(k)*16+i) != -1) vl++;
					else vl = 0;
					if(vl > 4){
						ts[SSCardLogic.type.T8] = 1;
						break;
					} 
				}
			}
		}
		return ts;
	}
	/** 获取指定牌型牌数据 */
	public static getTypeCards(t:number, c:number, cards: number[]): number[]{
		let cds = [];
		if(t == SSCardLogic.type.T5 || t == SSCardLogic.type.T8){
			let obj = SSCardLogic.colorNum(cards);
			let cv = SSCardLogic.getCardValue(c), cc = SSCardLogic.getCardColor(c);
			if(t == SSCardLogic.type.T5){
				for(let k in obj){
					let co = parseInt(k);
					if(obj[k] > 4){
						for(let i=0;i<cards.length;i++){
							if(co != SSCardLogic.getCardColor(cards[i])) continue;
							if((co == cc && SSCardLogic.getCardValue(cards[i]) > cv) || co > cc) cds.push(cards[i]);
							if(cds.length > 4) break;
						}
						if(cds.length > 4) break;
					}
					cds = [];
				}
			}else{
				for(let k in obj){
					let co = parseInt(k);
					if(obj[k] > 4){
						let valNum = SSCardLogic.valueNum(cards);
						for(let v in valNum){
							let vo = parseInt(v);
							if(vo < SSCardLogic.getCardValue(c)) continue;
							for(let i=0;i<cards.length;i++){
								if(co == SSCardLogic.getCardColor(cards[i]) && SSCardLogic.getCardValue(cards[i]) == vo) cds.push(cards[i]);
								if(cds.length > 4) break;
							}
						}
						if(cds.length > 4) break;
						cds = [];
					}
				}
			}
			if(cds.length < 5) cds = [];
		}else{
			let obj = SSCardLogic.valueNum(cards);
			c = SSCardLogic.getCardValue(c);
			if(t == SSCardLogic.type.T1){
				for(let k in obj){
					let v = parseInt(k);
					if(obj[k] > 1 && v > c){
						for(let i=0;i<cards.length;i++){
							if(v == SSCardLogic.getCardValue(cards[i])) cds.push(cards[i]);
							if(cds.length > 1) break;
						}
						break;
					}
				}
			}else if(t == SSCardLogic.type.T2){
				for(let k in obj){
					let v = parseInt(k);
					if(obj[k] > 1 && v > c){
						for(let i=0;i<cards.length;i++){
							if(v == SSCardLogic.getCardValue(cards[i])) cds.push(cards[i]);
							if(cds.length  % 2 == 0) break;
						}
						if(cds.length == 4) break;
						c++;
					}
				}
			}else if(t == SSCardLogic.type.T3){
				for(let k in obj){
					let v = parseInt(k);
					if(obj[k] > 2 && v > c){
						for(let i=0;i<cards.length;i++){
							if(v == SSCardLogic.getCardValue(cards[i])) cds.push(cards[i]);
							if(cds.length  == 3) break;
						}
						break;
					}
				}
			}else if(t == SSCardLogic.type.T4){
				let ov = c;
				for(let k in obj){
					let v = parseInt(k);
					if(v < c + 2 || v - ov != 1) cds = [];
					for(let i=0;i<cards.length;i++){
						if(v == SSCardLogic.getCardValue(cards[i])){
							cds.push(cards[i]);
							break;
						} 
					}
					if(cds.length == 5) break;
					ov = v;
				}
				if(cds.length < 5) cds = [];
			}else if(t == SSCardLogic.type.T6){
				let v3 = 0, v2 = 0;
				for(let k in obj){
					let v = parseInt(k);
					if(obj[k] > 2){
						if(v3 == 0) v3 = v;
						else if(v > c && v3 <= v) v3 = v;
					}else if(obj[k] > 1){
						if(v2 == 0) v2 = v;
						else if(v > c && v2 <= v) v2 = v;
					}
				}
				for(let i=0;i<cards.length;i++){
					if(v3 == SSCardLogic.getCardValue(cards[i])) cds.push(cards[i]);
					if(cds.length == 3) break;
				}
				for(let i=0;i<cards.length;i++){
					if(v2 == SSCardLogic.getCardValue(cards[i])) cds.push(cards[i]);
					if(cds.length == 5) break;
				}
			}else if(t == SSCardLogic.type.T7){
				for(let k in obj){
					let v = parseInt(k);
					if(obj[k] == 4 && v > c){
						for(let i=0;i<cards.length;i++){
							if(v == SSCardLogic.getCardValue(cards[i])) cds.push(cards[i]);
						}
						break;
					}
				}
			}
		}
		return cds;
	}
	/** 获取牌值数量 */
	public static valueNum(cards: number[]):any {
		let ret = {};
		for(let i=0;i<cards.length;i++){
			let v = SSCardLogic.getCardValue(cards[i]);
			if(!(v in ret)) ret[v] = 0;
			ret[v]++;
		}
		return ret;
	}
	/** 获取花色数量 */
	public static colorNum(cards: number[]):any {
		let ret = {};
		for(let i=0;i<cards.length;i++){
			let v = SSCardLogic.getCardColor(cards[i]);
			if(!(v in ret)) ret[v] = 0;
			ret[v]++;
		}
		return ret;
	}

	/**获取牌型 */
	public static getCardType(cardsData: Array<any>): number {
		return 0;
	}
	/** 获取牌值*/
	public static getCardValue(cardData: number): any {
		return cardData & this.maskValue;
	}
	/** 获取花色 **/
	public static getCardColor(cardData: number): number {
		return (cardData & this.maskColor) / 16;
	}
	/** 根据数值排序，从大到小 **/
	public static SortByValue(cardData: number[]): void {
		cardData.sort((left, right) => {
			if (this.getCardValue(left) > this.getCardValue(right)) {
				return -1;
			}
			else if (this.getCardValue(left) < this.getCardValue(right)) {
				return 1;
			}
			else {
				return 0;
			}
		});
	}
}